package com.yc.demo.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;

import lombok.extern.slf4j.Slf4j;

/**
 * <p></p>
 *
 * @author: YuanChilde
 * @date: 2020-02-13 14:17
 * @version: 1.0
 * Modification History:
 * Date    Author      Version     Description
 * -----------------------------------------------------------------
 * 2020-02-13 14:17    YuanChilde     1.0        新增
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

    @Pointcut("execution(public * com.yc.demo.controller..*.*(..))")
    public void pointcut() {}

    @Before("pointcut()")
    public void printParam(JoinPoint joinPoint){
        // 需开启exposeProxy=true,@EnableAspectJAutoProxy(proxyTargetClass=true,exposeProxy=true),proxyTargetClass:true-Cglib,false-JDK。默认为JDK，无实现接口使用Cglib
        // log.info("before method log done"+ AopContext.currentProxy().getClass());
        HttpSession session= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
        //获取请求的方法
        Signature sig = joinPoint.getSignature();
        String method = joinPoint.getTarget().getClass().getName() + "." + sig.getName();

        //获取请求的参数
        Object[] args = joinPoint.getArgs();
        //fastjson转换
        String params = JSON.toJSONString(args);

        //打印请求参数
        log.info(method + ":" + params);
    }

    /**
     * 含返回和异常
     */
    @After("pointcut()")
    public void doAfterPrint(){
        System.out.println("经纪人为球星表现疯狂鼓掌！");
    }

    @AfterReturning(returning = "obj", pointcut = "pointcut()")
    public void methodAfterReturing(Object obj) {
        log.info("--------------返回内容----------------");
        log.info("Response内容:" + JSON.toJSONString(obj));
        log.info("--------------返回内容----------------");
    }

    @AfterThrowing("pointcut()")
    public void doAfterThrowingPrint(){
        System.out.println("异常通知：球迷要求退票！");
    }

    @Pointcut("@annotation(print)")
    public void annotationPointcut(Print print){}

    @Around("annotationPointcut(print)")
    public Object around(ProceedingJoinPoint pjp, Print print) throws Throwable {
        //获取请求方法
        Signature sig = pjp.getSignature();
        String method = pjp.getTarget().getClass().getName() + "." + sig.getName();

        //获取请求的参数
        Object[] args = pjp.getArgs();
        //fastjson转换
        String params = JSONObject.toJSONString(args);

        //打印请求参数
        log.info("参数:" + method + ":" + params);

        //执行方法
        Object result = pjp.proceed();

        //打印返回结果
        log.info("返回结果:" + method + ":" + result);
        return result;
    }
}
